package com.itheima.app.utils;



import com.itheima.app.interceptor.UserHolder;
import com.itheima.domain.db.Log;
import com.itheima.service.mongo.UserLocationService;
import java.lang.reflect.Method;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.Map;

import com.itheima.util.JwtUtil;
import org.apache.commons.lang3.StringUtils;
import org.apache.dubbo.config.annotation.Reference;
import org.apache.rocketmq.spring.core.RocketMQTemplate;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Pointcut;
import org.aspectj.lang.reflect.MethodSignature;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import org.springframework.web.bind.annotation.*;

/**
 * @author : chun yang
 * @date : 19:40 2021/6/3
 */
/*
*   日志管理器
* */
@Component  //放入ioc容器中
@Aspect     //开始织入
public class MyLoadTransactionManager {

    @Autowired
    private RocketMQTemplate rocketMQTemplate;

    @Reference
    private UserLocationService userLocationService;

    @Pointcut("execution(* com.itheima.app.controller.*.*(..))")
    public void wh(){}


    //环绕
    @Around("wh()")//aop注解
    public Object wuhu(ProceedingJoinPoint pjp) throws Throwable {

        //执行原方法
        Object proceed = pjp.proceed();

        //获取方法(里面存储得是当前切点得所有信息)
        MethodSignature methodSignature = (MethodSignature) pjp.getSignature();
        //方法对象
        Method method = methodSignature.getMethod();
        String name = method.getName();//方法名

        Map<String, Object> map = null;

        //name属性值
        String nameType = "";
        //当前登录用户id
        Long userId = null;

        //判断方法上是否有RequestMapping
        if (method.isAnnotationPresent(PostMapping.class)){
            //有,获取PostMapping主键中name属性得值
            PostMapping mapping = method.getAnnotation(PostMapping.class);
            //获取mapping中name属性值
             nameType = mapping.name();
            //判断是否为空
            if (nameType.equals("")){
                //为空,不进行日志保存
                return proceed;
            }


            if (StringUtils.equals("0101",nameType)){
                //相等,说明走的是登录/注册方法
                //判断是登录还是注册
                map = (Map) proceed;
                Boolean isNew = (Boolean) map.get("isNew");
                if (isNew){//是注册
                    nameType = "0102";//注册操作类型
                }
                //登陆注册UserHolder为空,所以从token里获取
                //获取token里的userId
                String token = (String) map.get("token");
                Map tokenMap = JwtUtil.parseToken(token);//解密
                userId = Long.valueOf(tokenMap.get("id")+"");//获取id
            }
            System.out.println(name+"中name属性为: "+nameType);

        }else if (method.isAnnotationPresent(GetMapping.class)){
            //有,获取RequestMapping主键中name属性得值
            GetMapping mapping = method.getAnnotation(GetMapping.class);
            //获取mapping中name属性值
            nameType = mapping.name();
            //判断是否为空
            if (nameType.equals("")){
                //为空,不进行日志保存
                return proceed;
            }
            System.out.println(name+"中name属性为: "+nameType);
        }

        //创建long对象
        Log log = new Log();
        //判断是否为空,
        if (userId == null){
            //为空证明走的不是登陆注册,从UserHolder获取userId
            userId = UserHolder.get().getId();
        }
        log.setUserId(userId);//登录用户id
        log.setLogTime(new SimpleDateFormat("yyyy-MM-dd").format(new Date()));//操作时间
        //设置值
        log.setPlace(getAddress(log.getUserId()));//登陆地点

        log.setEquipment("华为1000");//登录设备,没有接口写死
        log.setType(nameType);//操作类型

        //发到消息中间件(Broker得Message Queue队列中)
        rocketMQTemplate.convertAndSend("tanhua-log",log);

        //返回原方法的执行结果
        return proceed;
    }

    //根据userId查询Address
    public String getAddress(Long userId){
        return userLocationService.findAddressByUserId(userId);
    }
}

